const app = getApp()
var dayjs = require('dayjs')
export default {
    /**
     * 获取蓝牙权限
     * */
    doGetSetting() {
        return new Promise((resolve, reject) => {
            wx.getSetting({
                success(res) {
                    if (!res.authSetting['scope.bluetooth']) {
                        //授权获取蓝牙权限
                        wx.authorize({
                            scope: 'scope.bluetooth',
                            success() {
                                console.log("成功获取蓝牙权限")
                                resolve()
                            },
                            fail() {
                                console.log("蓝牙权限获取失败")
                                reject()
                            }
                        })
                    } else {
                        console.log("成功获取蓝牙权限")
                        resolve()
                    }
                },
                fail(f) {
                    console.log(f)
                }
            })
        })
    },
    /**
     * 初始化蓝牙设备
     * */
    initBlueTooth () {
        return new Promise((resolve, reject) => {
            // wx.closeBluetoothAdapter()
            // 初始化蓝牙模块
            wx.openBluetoothAdapter({
                success: res => {
                    console.log('初始化蓝牙模块成功', res)
                    resolve()
                },
                fail (err) {
                    console.log('初始化蓝牙模块失败', err)
                    let eCode = ''
                    if (err.errCode && err.errCode !== 10001) {
                        eCode = ' 错误码：' + err.errCode
                    }
                    let contentMsg = '初始化失败，请检查蓝牙是否已开启'
                    const { system } = wx.getSystemInfoSync()
                    if (system.toLocaleLowerCase().includes('ios')) {
                        contentMsg =
                            '初始化失败，请检查蓝牙是否已开启或检查是否打开蓝牙授权'
                    }
                    reject({
                        message: contentMsg + eCode,
                        detail: err
                    })
                }
            })
        })
    },
    /**
     * 初始化蓝牙设备并监听设备状态变化
     */
    startConnect () {
        return new Promise((resolve, reject) => {
            /* 获取蓝牙适配器状态
             * discovering  是否正在搜索设备
             * available  蓝牙适配器是否可用
             * */
            this.getBluetoothAdapterState()
                .then(() => {
                    // const {available} = res
                    // if (available) {
                    //     console.log('蓝牙适配器可用，无需初始化')
                    //     resolve()
                    // } else {
                    console.log('蓝牙适配器不可用，初始化')
                    this.initBlueTooth()
                        .then(() => {
                            resolve()
                        })
                        .catch(e => {
                            reject(e)
                        })
                    // }
                })
                .catch(e => {
                    console.log('蓝牙适配器不可用，初始化', e)
                    this.initBlueTooth()
                        .then(() => {
                            resolve()
                        })
                        .catch(e => {
                            reject(e)
                        })
                })
        })
    },
    /**
     * 获取本机蓝牙适配器状态
     * https://developers.weixin.qq.com/miniprogram/dev/api/wx.getBluetoothAdapterState.html
     */
    getBluetoothAdapterState () {
        return new Promise((resolve, reject) => {
            wx.getBluetoothAdapterState({
                success: res => {
                    console.log('获取本机蓝牙适配器状态成功', res)
                    resolve(res)
                },
                fail: e => {
                    console.log('获取本机蓝牙适配器状态失败', e)
                    reject(e)
                }
            })
        })
    },
    /**
     * 搜索蓝牙设备
     * */
    startSearchBlueTooth (services = []) {
        return new Promise((resolve, reject) => {
            wx.startBluetoothDevicesDiscovery({
                services,
                allowDuplicatesKey: true,
                interval: 0,
                success: res => {
                    console.log('启动搜索蓝牙设备成功', res)
                    resolve(res)
                },
                fail: err => {
                    console.log('启动搜索蓝牙设备失败', err)
                    reject(err)
                }
            })
        })
    },
    /**
     * 监听寻找到新设备的事件
     * */
    onBluetoothDeviceFound (services = []) {
        return new Promise((resolve, reject) => {
              wx.getBluetoothDevices({
                success: (res) => {
                    var blueToothList = []
										console.log(res.devices,'搜素到的设备')
                    for (var i = 0; i < res.devices.length; i++) {
                        if (res.devices[i].name != "未知设备") {
                            blueToothList.push(res.devices[i])
                        }
                    }
                    resolve(blueToothList)
                },
                fail: function () {
                    console.log("搜索蓝牙设备失败")
                }
            })
        })
    },
    /**
     * 连接蓝牙设备
     * */
    createBLEConnection(deviceId) {
        return new Promise((resolve, reject) => {
            wx.createBLEConnection({
                deviceId: deviceId,
                success: (res) => {
                    wx.stopBluetoothDevicesDiscovery({
                        success: () => {
                            console.log('连接蓝牙成功之后关闭蓝牙搜索,避免耗电');
                        }
                    }),
                    //连接成功，开始监听蓝牙连接状态，断开后重连
                    resolve(res)
                  // 如果有读写操作则下面进行 获取蓝牙设备所有service
                },
                fail: (err) => {
                    console.log(err,'err')
                    reject(err)
                },
              })
        })
    },
    /**
     * 断开蓝牙设备
     * */
    closeBLEConnection(deviceId) {
        return new Promise((resolve, reject) => {
            wx.closeBLEConnection({
                deviceId: deviceId,
                success: (res) => {
                    resolve(res)
                  // 如果有读写操作则下面进行 获取蓝牙设备所有service
                },
                fail: (err) => {
                    console.log(err,'err')
                    reject(err)
                },
              })
        })
    },
    
    /**
     * 停止搜索蓝牙设备
     * */
    stopSearchBlueTooth () {
        return new Promise((resolve, reject) => {
            wx.stopBluetoothDevicesDiscovery({
                success: res => {
                    console.log('停止搜索蓝牙设备', res)
                    resolve(res)
                },
                fail: err => {
                    console.log('停止搜索蓝牙设备失败', err)
                    reject(err)
                }
            })
        })
    },
    /**
     * 关闭蓝牙模块
     * */
    closeBluetoothAdapter() {
        return new Promise((resolve, reject) => {
            wx.closeBluetoothAdapter({
                success: res => {
                    console.log('关闭蓝牙模块成功', res)
                    resolve(res)
                },
                fail: err => {
                    console.log('关闭蓝牙模块成功失败', err)
                    reject(err)
                }
            })
        })
    },
    /**
     * 获取处于已连接状态的设备
     */
    getConnectedBluetoothDevices () {
        return new Promise((resolve, reject) => {
            wx.getConnectedBluetoothDevices({
                services: [],
                success: res => {
                    console.log('获取处于已连接状态的设备', res)
                    resolve(res.devices)
                },
                fail: e => {
                    console.log('获取处于已连接状态的设备失败', e)
                    reject(e)
                }
            })
        })
    },

    /**
     * 获取蓝牙设备所有服务，获取特征值中用到 已废弃
     * @param deviceId {String}  设备id
     * @param options {Object}  配置信息
     * @param options.isWrite {Boolean}  是否过滤可读属性
     * */
    getBLEDeviceServices (deviceId, options = {}) {
        let { isWrite = true, readDir = true } = options

        return new Promise((resolve, reject) => {
            // 获取蓝牙设备所有服务
            wx.getBLEDeviceServices({
                deviceId,
                success: res => {
                    const services = res.services
                    for (let ser of services) {
											if (ser.uuid === this.getServiceUUID()) {
												console.log(ser.uuid, 'ser.uuidser.uuidser.uuidser.uuid')
												wx.getBLEDeviceCharacteristics({
													deviceId,
													serviceId: this.getServiceUUID(),
													success: res => {
															res.characteristics.forEach(item => {
																	if (item.properties.notify && item.uuid === this.getNotifyUUID()) {
																			const data = {
																					deviceId: deviceId,
																					serviceId: this.getServiceUUID(),
																					characteristicId: item.uuid
																			}
																			console.log(data, 'toggleNotifytoggleNotifytoggleNotify')
																			this.toggleNotify(true, data).then(res => {
																				resolve(res)
																			})
																	}
															})
													},
													fail: e => {
															console.log('获取特征值characteristic失败', e)
															reject({
																	errMsg: '获取特征值失败'
															})
													}
												})
											}
                    }
                },
                fail: e => {
                    console.log('获取蓝牙设备所有 service失败', e)
                    reject(e)
                }
            })
        })
    },
		/**
     * 关闭蓝牙
     * @param value {String} 要发送字符串
     */
		closeBLE(deviceId) {
			wx.closeBLEConnection({
				deviceId: deviceId,
				success (res) {
					console.log(res)
				}
			})
			wx.closeBluetoothAdapter({
				success (res) {
					console.log(res)
				}
			})
		},
    /**
     * 连接后获取设备 MAC 地址
     * @param {Array} deviceId 设备ID
     * @param {Array} serviceId 服务ID
     * @param {String} characteristicId 特征值ID
     * */
    getMacDir (deviceId, serviceId, characteristicId) {
        return new Promise((resolve, reject) => {
            wx.readBLECharacteristicValue({
                deviceId,
                serviceId,
                characteristicId,
                success: res => {
                    console.log(
                        '读取低功耗蓝牙设备的特征值的二进制数据值成功',
                        res
                    )
                },
                fail: e => {
                    const eObj = {
                        message: '读取低功耗蓝牙设备的特征值的二进制数据值失败',
                        detail: e
                    }
                    reject(eObj)
                }
            })
        })
    },
    newGietMacDir (deviceId, serviceId, characteristicId) {
        return new Promise((resolve, reject) => {
            // 获取服务列表
            this.initService2characteristic(deviceId, serviceId).then(() => {
                wx.onBLECharacteristicValueChange(res => {
                    // console.log('二进制数据值：', res)
                    const mac = this.macBuf2String(res.value)
                        .join('')
                        .toLocaleUpperCase()
                    // console.log('MAC地址', mac)
                    resolve(mac)
                })
                console.log('连接后获取设备MAC地址')
                console.log(serviceId, characteristicId)
                wx.readBLECharacteristicValue({
                    deviceId,
                    serviceId,
                    characteristicId,
                    success: res => {
                        console.log(
                            '读取低功耗蓝牙设备的特征值的二进制数据值成功',
                            res
                        )
                    },
                    fail: e => {
                        const eObj = {
                            message:
                                '读取低功耗蓝牙设备的特征值的二进制数据值失败',
                            detail: e
                        }
                        console.error(eObj)
                        reject(eObj)
                    }
                })
            })
        })
    },
    /**
     * 获取服务列表和特征值已完成后续动作
     * */
    initService2cs (deviceId, serviceId) {
        return new Promise((resolve, reject) => {
            // 获取服务列表
            wx.getBLEDeviceServices({
                deviceId,
                success: s => {
                    wx.getBLEDeviceCharacteristics({
                        deviceId,
                        serviceId,
                        success: c => {
                            resolve({ s, c })
                        },
                        fail: e => {
                            reject(e)
                        }
                    })
                },
                fail: e => {
                    reject(e)
                }
            })
        })
    },
		getNotifyUUID() {
			return "0000FFF4-0000-1000-8000-00805F9B34FB";
		},
		getServiceUUID() {
			return "0000FFF0-0000-1000-8000-00805F9B34FB";
		},
    /**
     * 关闭/开启notify 默认开启
     * @param state {Boolean}  @default true -开启/关闭Notify
     * @param options {Object}  @default {}
     * */
    toggleNotify (state = true, options = {}) {
        const { deviceId, serviceId, characteristicId } = options
        return new Promise((resolve, reject) => {
            wx.notifyBLECharacteristicValueChange({
                state,
                deviceId,
                serviceId,
                characteristicId,
                success: res => {
                    wx.onBLECharacteristicValueChange((res) => {
                        //获取设备
                        // const device = this.getConnectedDeviceWithDeviceID(deviceId)
                        const valueFor16 = this.ab2hex(res.value)
												if (valueFor16.length > 8) {  
													let str = valueFor16.substring(2, 4);
													if (str === "40") {  
															// 血压 d0动态数据 d1测量完整数据  
															let type = valueFor16.substring(4, 6);  
															if (type === "d1") {  
																	let gy_0x = valueFor16.substring(12, 14);  
																	let dy_0x = valueFor16.substring(16, 18);  
																	let pluse_0x = valueFor16.substring(24, 26);  
										
																	let gy = parseInt(gy_0x, 16);  
																	let dy = parseInt(dy_0x, 16);  
																	let pluse = parseInt(pluse_0x, 16);
																	const data = {
																		success: true,
																		gy: gy,
																		dy: dy,
																		pluse: pluse,

																	}
																	console.log(gy, 'gygy')
																	resolve(data)
															} else if (type === "d3") {
																resolve({success: false})
															}
													}  
											} 
                      })
                },
                fail: e => {
                    reject(e)
                }
            })
        })
    },
		decrypt(sourceStr, decryptKey) {  
			let result = '';  
			for (let i = 0; i < sourceStr.length; i++) {  
				let k = sourceStr.charCodeAt(i);  
				if (k >= 97) { // 'a' ASCII code  
					k -= 36;  
				} else if (k >= 65) { // 'A' ASCII code  
					k -= 10;  
				} else {  
					k = k - 48; // '0' ASCII code  
				}  
				k += 62 * 3;  
				k -= decryptKey[i % 4];  
				k = k % 62;  
				if (k >= 36) {  
					k += 97; // 'a' ASCII code  
				} else if (k >= 10) {  
					k += 65; // 'A' ASCII code  
				} else {  
					k += 48; // '0' ASCII code  
				}  
				result += String.fromCharCode(k);  
			}  
			return result;  
		},
    /**
     * 获取绑定的默认设备，用于自动连接
     * */
    async getDefaultDevice () {
        try {
            console.log('获取默认设备')
            const res = await this.getHistoryDevIces()
            console.log(res)
            if (!res) {
                return Promise.reject({
                    code: 'list_none',
                    message: '您还没有添加设备'
                })
            }
            let list = []
            for (let [, value] of Object.entries(res)) {
                list.push(value)
            }
            if (list.length === 0) {
                return null
            } else if (list.length === 1) {
                return list[0]
            } else {
                let arr = list.filter(item => {
                    return item.defaultDevice === true
                })
                if (arr.length > 0) {
                    return arr[0]
                } else {
                    // 存在多个且没有默认设备
                    return Promise.reject({
                        code: 'default_none',
                        message:
                            '您还没有绑定默认设备哦，请在 我的 > 我的设备 页面中进行设备绑定，绑定完成后再次点击上秤即可开始进行检测'
                    })
                }
            }
        } catch (e) {
            return Promise.reject(e)
        }
    },

    /**
     * 指令发送到蓝牙
     * @param value {String} 要发送字符串
     */
    sendDataToBLE (value, deviceId) {
        return new Promise((resolve, reject) => {
            console.log('发送的数据------------------------------')
            console.log(value)
            const buffer = this.string2buf(value)
            console.log('发送的Buffer数据-----------------------------')
            console.log(buffer)
						console.log(deviceId, '--', this.getServiceUUID(), '--', this.getWriteUUID())
            wx.writeBLECharacteristicValue({
                deviceId: deviceId,
                serviceId: this.getServiceUUID(),
                characteristicId: this.getWriteUUID(),
                value: buffer,
                success: res => {
                    console.log('发送成功', res)
                    resolve(res)
                },
                fail: e => {
                    console.error('发送失败', e)
                    reject(e)
                }
            })
        })
    },
		getWriteUUID() {
			return "0000FFE1-0000-1000-8000-00805F9B34FB";
		},
    /**
     * ArrayBuffer转16进制字符串
     * */
    ab2hex (buffer) {
        return this.ab2hexArr(buffer).join('')
    },
    /**
     * ArrayBuffer转16进制字符串数组
     * */
    ab2hexArr (buffer) {
        return Array.prototype.map.call(new Uint8Array(buffer), function (bit) {
            return ('00' + bit.toString(16)).slice(-2)
        })
    },
    // 将16进制的内容转成我们看得懂的字符串内容
    hexCharCodeToStr(hexCharCodeStr) {
        var trimedStr = hexCharCodeStr.trim();
        var rawStr = trimedStr.substring(0, 2).toLowerCase() === "0x" ? trimedStr.substring(2) : trimedStr;
        var len = rawStr.length;
        if (len % 2 !== 0) {
                alert("存在非法字符!");
                return "";
        }
        var curCharCode;
        var resultStr = [];
        for (var i = 0; i < len; i = i + 2) {
                curCharCode = parseInt(rawStr.substring(i, 2), 16);
                resultStr.push(String.fromCharCode(curCharCode));
        }
        return resultStr.join("");
    },
    // ArrayBuffer转数字数组
    arrayBufferToNumberArray(buffer) {
        var numberArr = Array.prototype.map.call(
            new Uint8Array(buffer),

            function (bit) {
                return bit
            }
        )
        return numberArr
    },
    /**
     * 字符串转16进制ArrayBuffer
     * */
    string2buf (str) {
        // 首先将字符串转为16进制
        let val = ''
        for (let i = 0; i < str.length; i++) {
            if (val === '') {
                val = str.charCodeAt(i).toString(16)
            } else {
                val += ',' + str.charCodeAt(i).toString(16)
            }
        }
        // 将16进制转化为ArrayBuffer
        return new Uint8Array(
            val.match(/[\da-f]{2}/gi).map(function (h) {
                return parseInt(h, 16)
            })
        ).buffer
    },
    /**
     *
     * */
    macBuf2String (buffer) {
        let hexArr = this.ab2hex(buffer)
        return [
            hexArr[7],
            hexArr[6],
            hexArr[5],
            hexArr[2],
            hexArr[1],
            hexArr[0]
        ]
    },
    /**
     * ArrayBuffer转字符串
     * */
    buf2string (buffer) {
        let arr = Array.prototype.map.call(new Uint8Array(buffer), x => x)
        return arr
            .map(char => {
                return String.fromCharCode(char)
            })
            .join('')
    },
    // 日期效验
    isDate (str) {
        if (!str) return false
        const r = str.match(/^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/)
        if (!r) return false
        const d = new Date(r[1], Number(r[3]) - 1, r[4])
        return (
            d.getFullYear() == r[1] &&
            d.getMonth() + 1 == r[3] &&
            d.getDate() == r[4]
        )
    },
    // 根据出生日期获取周岁年龄
    getAge (strBirthday) {
        let returnAge
        let strBirthdayArr = strBirthday.split('-')
        let birthYear = strBirthdayArr[0]
        let birthMonth = strBirthdayArr[1]
        let birthDay = strBirthdayArr[2]
        let d = new Date()
        let nowYear = d.getFullYear()
        let nowMonth = d.getMonth() + 1
        let nowDay = d.getDate()
        if (nowYear == birthYear) {
            returnAge = 0 //同年则为0岁
        } else {
            let ageDiff = nowYear - birthYear //年之差
            if (ageDiff > 0) {
                if (nowMonth == birthMonth) {
                    let dayDiff = nowDay - birthDay //日之差
                    if (dayDiff < 0) {
                        returnAge = ageDiff - 1
                    } else {
                        returnAge = ageDiff
                    }
                } else {
                    let monthDiff = nowMonth - birthMonth //月之差
                    if (monthDiff < 0) {
                        returnAge = ageDiff - 1
                    } else {
                        returnAge = ageDiff
                    }
                }
            } else {
                returnAge = -1 //返回-1 表示出生日期输入错误 晚于今天
            }
        }
        return returnAge // 返回周岁年龄
    }
}
